#!/usr/bin/perl
use warnings;
use strict;
use Getopt::Long;
use File::Path qw/mkpath rmtree/;
use File::Temp qw/tempdir/;
use File::Basename qw/basename dirname/;
use File::Find qw/find/;
use File::Copy::Recursive qw/dircopy/;

my $rev_pat = qr/\d+|BASE|COMMITTED|HEAD|PREV
                |\{\d{2,4}-\d{2}-\d{2}\}/x;
my $temp_prefix = 'upc-spec-diff-XXXX';
my ($dir, $force, $help, $keep, $rev);
my ($rev_before, $rev_after);
my ($dir_before, $dir_after, $rev_after_opt);
my @spec_files;

GetOptions('revision|r=s' => \$rev,
           'dir|d=s' => \$dir,
	   'force|f' => \$force,
	   'keep|k' => \$keep,
	   'help|h' => \$help);

die "not at top of UPC specification tree\n"
  unless -d 'common' && -d 'lang' && -d 'lib';
die "not an SVN working copy of the UPC specification tree\n"
  unless -d '.svn';

$rev_before = '48';
$rev_after = undef;
$rev_after_opt   = '';
if (defined($rev)) {
  ($rev_before, $rev_after) = ($rev =~ /^($rev_pat)(?::($rev_pat))?$/);
  die "invalid svn revision specifier: $rev\n"
    unless defined($rev_before);
  $rev_after_opt = "-r${rev_after}" if defined($rev_after);
}

$dir = 'diff' if !defined($dir);
if (-e $dir) {
  die "not a directory: $dir\n"
    unless -d $dir;
  die "output directory already exists: $dir\n"
    unless defined($force);
  rmtree ($dir); 
}
mkpath ($dir);

if (!defined ($rev_after)) {
}

# $dir_before = tempdir ($temp_prefix, CLEANUP => !$keep);
# $dir_after  = tempdir ($temp_prefix, CLEANUP => !$keep);
# if ($keep) {
#   warn "'before' specification tree: $dir_before\n";
#   warn "'after' specification tree: $dir_after\n";
# }

$dir_before = "${dir}/before";
$dir_after  = "${dir}/after";

!system "svn export -q -r$rev_before . $dir_before"
  or die "cannot export SVN version $rev_before "
         . "into the 'before' tree\n";

!system "svn export -q $rev_after_opt . $dir_after"
  or die "cannot export SVN "
         . (defined ($rev_after) ? "version $rev_after"
	                         : "current working copy")
         . " into the 'after' tree\n";

dircopy $dir_after, $dir
 or die "copy ${dir_after} to ${dir} failed: $!\n";

find (sub {push @spec_files, $File::Find::name
             if /-spec.tex$/;}, $dir_after);

for my $spec_after (@spec_files) {
  my $spec_after_dir = dirname($spec_after);
  (my $spec_before_dir = $spec_after_dir) =~ s/^${dir_after}/${dir_before}/;
  (my $spec_file = $spec_after) =~ s{/after}{};
  (my $spec_dir = $spec_after_dir) =~ s{/after}{};
  for my $tex_after (<$spec_after_dir/*.tex>) {
    (my $tex_before = $tex_after) =~ s/^${dir_after}/${dir_before}/;
    (my $tex_diff = $tex_after) =~ s{/after}{};
    print "latexdiff $tex_before $tex_after > $tex_diff\n";
    !system "latexdiff $tex_before $tex_after > $tex_diff\n";
  }
}
